import logging
import allure
import pytest
from utils.send_request import send_jdbc_request
from utils.get_keywords import GetKeywords


class DataAssert(object):
    """
    断言处理基础类
    """
    def http_assert(self,case,res):
        pass

class SingleAssert(DataAssert):
    """子类，负责单个断言处理"""
    @allure.step("3.HTTP响应断言")
    def http_assert(self,case, res):
        if case["check"]:
            # chen：修改
            result = GetKeywords.get_keyword(res,case["check"])
            logging.info(f"3.HTTP响应断言内容: 实际结果({result}) == 预期结果({case['expected']})")
            assert result == case["expected"]
        else:
            logging.info(f"3.HTTP响应断言内容: 预期结果({case['expected']}) in 实际结果({res.text})")
            assert case["expected"] in res.text


class MultipleAssert(DataAssert):
    """子类，负责多重断言处理"""
    @allure.step("3.HTTP多重响应断言")
    def http_assert(self,case, res):
        from utils.base_asserts import MainAsserts
        MainAsserts(eval(case["check"]),res).main_assert()

        # # 遍历字典断言，把想要做的多重断言都提出来断言
        # for key,value in checks.items():
        #     result = GetKeywords.get_keyword(res, key)
        #     pytest.assume(result == value)


def obtain_processor(case):
    """
    数据处理器
    :param case:用例数据
    :return:不同的对象
    """
    try:
        isinstance(eval(case["check"]), dict)
        return MultipleAssert()
    except NameError:
        # 老逻辑 单个断言
        return SingleAssert()

def http_assert(case,res):
    """
    真正调用的逻辑，后续更改无论怎么加断言，都是调用这个函数，主程序不改变
    :param case:
    :param res:
    :return:
    """
    op = obtain_processor(case)
    op.http_assert(case,res)



class BaseJABC(object):
    """jdbc断言基础"""
    def jdbc_assert(self,case):
        pass

class SingleJDBCAssert(BaseJABC):
    """单个数据库断言"""
    def jdbc_assert(self,case):
        """数据库单个断言"""
        if case["sql_check"] and case["sql_expected"]:
            with allure.step("3.JDBC响应断言"):
                result = send_jdbc_request(case["sql_check"])
                logging.info(f"3.JDBC响应断言内容: 实际结果({result}) == 预期结果({case['sql_expected']})")
                assert result == eval(case["sql_expected"])


class MultipleJDBCAssert(BaseJABC):
    """数据库多重断言"""
    def jdbc_assert(self,case):
        """数据库多重断言"""
        if case["sql_check"]:
            with allure.step("3.JDBC响应断言"):
                # 把sql断言转成列表
                sql_check_list = eval(case["sql_check"])
                for check in sql_check_list:
                    result = send_jdbc_request(check["sql"])
                    logging.info(f"3.JDBC响应断言内容: 实际结果({result}) == 预期结果({check['assertions']})")
                    pytest.assume(result == check['assertions'])


def obtain_jdbc_processor(case):
    """
    jdbc数据处理器
    :param case:用例数据
    :return:不同的对象
    """
    try:
        isinstance(eval(case["sql_check"]), list)
        return MultipleJDBCAssert()
    except Exception:
        # 老逻辑 单个断言
        return SingleJDBCAssert()

def jdbc_assert(case):
    """
    真正调用的逻辑，后续更改无论怎么加断言，都是调用这个函数，主程序不改变
    :param case:
    :param res:
    :return:
    """
    op = obtain_jdbc_processor(case)
    op.jdbc_assert(case)
